﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FySystem.Job.JobTask
{
    /// <summary>
    /// 创建指定时间点执行的定时任务
    /// </summary>
    public class TimerJob : JobBase
    {
        /// <summary>
        /// 小时执行条件
        /// </summary>
        public Func<int, bool> Hour { get; private set; }
        /// <summary>
        /// 分钟执行条件
        /// </summary>
        public Func<int, bool> Minute { get; private set; }
        /// <summary>
        /// 秒执行条件
        /// </summary>
        public Func<int, bool> Second { get; private set; }

        /// <summary>
        /// 创建指定时间点执行的定时任务，执行时间间隔不能超过1天，否则会计算不到下一条数据的执行时间
        /// </summary>
        /// <param name="jobName">名称</param>
        /// <param name="jobExecuter">回调</param>
        /// <param name="hour">小时执行条件，如果传null，则表示忽略小时条件</param>
        /// <param name="min">分钟执行条件，如果传null，则表示忽略分钟条件</param>
        /// <param name="second">秒执行条件，如果传null，则表示忽略秒条件</param>
        public TimerJob(string jobName, FyJobContext.FyJobAction jobExecuter, Func<int, bool> hour, Func<int, bool> min, Func<int, bool> second) : base(jobName, jobExecuter)
        {
            try
            {
                if (hour == null && min == null && second == null)
                    throw new Exception("hour、min、second至少要有一个不为空~");

                Hour = hour;
                Minute = min;
                Second = second;

                //初始化
                InitializeJob();
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 初始化
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        private void InitializeJob()
        {
            try
            {
                //是否执行
                ExecuteTrigger = job =>
                {
                    bool res = false;
                    try
                    {
                        if (DateTime.Now >= NextExecuteTime)
                            res = true;
                    }
                    catch { }
                    return res;
                };

                //下次执行时间
                NextExecuteTimeGenerator = job =>
                {
                    DateTime res = DateTime.MaxValue;
                    try
                    {
                        DateTime startTime = DateTime.Now;
                        DateTime endTime = startTime.AddDays(1);

                        while (startTime <= endTime)
                        {
                            startTime = startTime.AddSeconds(1);

                            //判断小时
                            if (Hour != null)
                            {
                                if (Hour(startTime.Hour) == false)
                                    continue;
                            }

                            //判断分钟
                            if (Minute != null)
                            {
                                if (Minute(startTime.Minute) == false)
                                    continue;
                            }

                            //判断秒
                            if (Second != null)
                            {
                                if (Second(startTime.Second) == false)
                                    continue;
                            }

                            res = startTime;
                            break;
                        }
                    }
                    catch { }
                    return res;
                };
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
}
